<template>
  <div class="toolbar-container">
    <div class="left-toolbar">
      <el-button link type="primary" :disabled="undoDisabled" :title="i18nt('designer.toolbar.undoHint')"
                 @click="undoHistory">
        <svg-icon icon-class="undo" />
      </el-button>
      <el-button link type="primary" :disabled="redoDisabled" :title="i18nt('designer.toolbar.redoHint')"
                 @click="redoHistory">
        <svg-icon icon-class="redo" />
      </el-button>
      <el-button @click="showLogicEditorFlag=true"> 逻辑编排</el-button>

      <el-button-group v-if="showLayoutTypeButton" style="margin-left: 20px">
        <el-button :type="layoutType === 'PC' ? 'info': ''" @click="changeLayoutType('PC')">
          {{ i18nt('designer.toolbar.pcLayout') }}
        </el-button>
        <el-button :type="layoutType === 'Pad' ? 'info': ''" @click="changeLayoutType('Pad')">
          {{ i18nt('designer.toolbar.padLayout') }}
        </el-button>
        <el-button :type="layoutType === 'H5' ? 'info': ''" @click="changeLayoutType('H5')">
          {{ i18nt('designer.toolbar.mobileLayout') }}
        </el-button>
      </el-button-group>
      <el-button style="margin-left: 20px" :title="i18nt('designer.toolbar.nodeTreeHint')" @click="showNodeTreeDrawer">
        <svg-icon icon-class="node-tree" />
      </el-button>
    </div>

    <div class="center-toolbar">
      <el-button type="primary" @click="handleSaveForm">保存</el-button>
    </div>

    <div class="right-toolbar">
      <el-scrollbar>
        <div class="right-toolbar-con">
          <!--          <el-button @click="getMockUser()">testMock</el-button>-->
          <el-button v-if="showToolButton('clearDesignerButton')" link type="primary" @click="clearFormWidget">
            <svg-icon icon-class="el-delete" />
            {{ i18nt('designer.toolbar.clear') }}
          </el-button>
          <el-button v-if="showToolButton('previewFormButton')" link type="primary" @click="previewForm">
            <svg-icon icon-class="el-view" />
            {{ i18nt('designer.toolbar.preview') }}
          </el-button>
          <el-button v-if="showToolButton('importJsonButton')" link type="primary" @click="importJson">
            {{ i18nt('designer.toolbar.importJson') }}
          </el-button>
          <el-button v-if="showToolButton('exportJsonButton')" link type="primary" @click="exportJson">
            {{ i18nt('designer.toolbar.exportJson') }}
          </el-button>
          <el-button v-if="showToolButton('exportCodeButton')" link type="primary" @click="exportCode">
            {{ i18nt('designer.toolbar.exportCode') }}
          </el-button>
          <el-button v-if="showToolButton('generateSFCButton')" link type="primary" @click="generateSFC">
            <svg-icon icon-class="vue-sfc" />
            {{ i18nt('designer.toolbar.generateSFC') }}
          </el-button>
          <template v-for="(idx, slotName) in $slots">
            <slot :name="slotName"></slot>
          </template>
        </div>
      </el-scrollbar>
    </div>

    <div v-if="showPreviewDialogFlag" class="preview_wrapper">
      <el-dialog :title="i18nt('designer.toolbar.preview')"
                 v-model="showPreviewDialogFlag"
                 top="0"
                 :modal="false"
                 :show-close="true"
                 :close-on-click-modal="false"
                 :close-on-press-escape="false"
                 :destroy-on-close="true"
                 :append-to-body="false"
                 append-to="#vfApp"
                 class="small-padding-dialog vf-preview-dialog"
      >
        <!--        <template #header>
                  <el-button @click="postToNodeRed"> 给node-red发送数据</el-button>
                </template>-->
        <div class="form-render-wrapper"
             :class="[layoutType === 'H5' ? 'h5-layout' : (layoutType === 'Pad' ? 'pad-layout' : '')]">
          <VFormRender ref="preForm" :form-json="formJson" :form-data="testFormData" :preview-state="true"
                       :option-data="testOptionData" :global-dsv="designerDsv"
                       @appendButtonClick="testOnAppendButtonClick"
                       @buttonClick="testOnButtonClick"
                       @dataTableSelectionChange="testDTSC"
                       @operationButtonClick="testOBC"
                       @myEmitTest="onMyEmitTest"
                       @formChange="handleFormChange">
            <template #slot1>
              <div>test1</div>
            </template>
            <template #slot2>
              <div>test2</div>
            </template>
            <template #slot3>
              <div>test3</div>
            </template>
            <template #slot4>
              <div>test4</div>
            </template>
            <template #slot5>
              <div>test5</div>
            </template>
          </VFormRender>
        </div>
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" @click="getFormData">{{ i18nt('designer.hint.getFormData') }}</el-button>
            <el-button type="primary" @click="resetForm">{{ i18nt('designer.hint.resetForm') }}</el-button>
            <el-button type="primary" @click="setFormDisabled">{{ i18nt('designer.hint.disableForm') }}</el-button>
            <el-button type="primary" @click="setFormEnabled">{{ i18nt('designer.hint.enableForm') }}</el-button>
            <el-button type="primary" plain @click="switchReadMode">{{ i18nt('designer.hint.switchReadMode') }}
            </el-button>
            <el-button @click="showPreviewDialogFlag = false">{{ i18nt('designer.hint.closePreview') }}</el-button>
            <!--            <el-button v-if="false" @click="testSetFormJson">setFormJson</el-button>
                        <el-button v-if="false" @click="testSubFormHide">Test SFH</el-button>
                        <el-button v-if="false" @click="testSetFormData">Test SFD</el-button>-->
          </div>
        </template>
      </el-dialog>
    </div>

    <div v-if="showImportJsonDialogFlag" class="">
      <!--      <el-dialog v-model="showImportJsonDialogFlag"
                       :show-close="true" class="drag-dialog small-padding-dialog" :append-to-body="true" center
                       :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true"
                       draggable
            >

              <el-alert type="info" :title="" show-icon class="alert-padding"></el-alert>-->
      <code-editor
        :title="i18nt('designer.toolbar.importJson')"
        :mode="'json'"
        :readonly="false"
        :event-param="i18nt('designer.hint.importJsonHint')"
        v-model="importTemplate"
        v-model:show="showImportJsonDialogFlag"
      >
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" @click="doJsonImport">
              {{ i18nt('designer.hint.import') }}
            </el-button>
            <el-button @click="showImportJsonDialogFlag = false">
              {{ i18nt('designer.hint.cancel') }}
            </el-button>
          </div>
        </template>
      </code-editor>
      <!--      </el-dialog>-->
    </div>

    <div v-if="showExportJsonDialogFlag" class="">

      <code-editor :mode="'json'"
                   :title="i18nt('designer.toolbar.exportJson')"
                   :readonly="true"
                   :show-close="true"
                   v-model="jsonContent"
                   v-model:show="showExportJsonDialogFlag"
      >
        <template #footer>
          <el-button type="primary" class="copy-json-btn" :data-clipboard-text="jsonRawContent" @click="copyFormJson">
            {{ i18nt('designer.hint.copyJson') }}
          </el-button>
          <el-button @click="saveFormJson">{{ i18nt('designer.hint.saveFormJson') }}</el-button>
          <el-button @click="showExportJsonDialogFlag = false">
            {{ i18nt('designer.hint.closePreview') }}
          </el-button>
        </template>
      </code-editor>
    </div>

    <div v-if="showExportCodeDialogFlag" class="">
      <el-dialog
        draggable
        :title="i18nt('designer.toolbar.exportCode')" v-model="showExportCodeDialogFlag"
        :show-close="true" class="drag-dialog small-padding-dialog" center append-to-body
        width="65%" :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true">
        <el-tabs type="border-card" class="no-box-shadow no-padding" v-model="activeCodeTab">
          <el-tab-pane label="Vue" name="vue">
            <code-editor :mode="'html'" :readonly="true" v-model="vueCode" :user-worker="false"></code-editor>
          </el-tab-pane>
          <el-tab-pane label="HTML" name="html">
            <code-editor :mode="'html'" :readonly="true" v-model="htmlCode" :user-worker="false"></code-editor>
          </el-tab-pane>
        </el-tabs>
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" class="copy-vue-btn" :data-clipboard-text="vueCode" @click="copyVueCode">
              {{ i18nt('designer.hint.copyVueCode') }}
            </el-button>
            <el-button type="primary" class="copy-html-btn" :data-clipboard-text="htmlCode" @click="copyHtmlCode">
              {{ i18nt('designer.hint.copyHtmlCode') }}
            </el-button>
            <el-button @click="saveVueCode">{{ i18nt('designer.hint.saveVueCode') }}</el-button>
            <el-button @click="saveHtmlCode">{{ i18nt('designer.hint.saveHtmlCode') }}</el-button>
            <el-button @click="showExportCodeDialogFlag = false">
              {{ i18nt('designer.hint.closePreview') }}
            </el-button>
          </div>
        </template>
      </el-dialog>
    </div>

    <div v-if="showFormDataDialogFlag" class="">
      <el-dialog
        draggable
        :title="i18nt('designer.hint.exportFormData')" v-model="showFormDataDialogFlag"
        :show-close="true" class="nested-drag-dialog dialog-title-light-bg" center
        :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true"
        :append-to-body="true">
        <div style="border: 1px solid #DCDFE6">
          <code-editor v-model:show="showFormDataDialogFlag" :mode="'json'" :readonly="true" :model-value="formDataJson"></code-editor>
        </div>
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" class="copy-form-data-json-btn" :data-clipboard-text="formDataRawJson"
                       @click="copyFormDataJson">
              {{ i18nt('designer.hint.copyFormData') }}
            </el-button>
            <el-button @click="saveFormData">{{ i18nt('designer.hint.saveFormData') }}</el-button>
            <el-button @click="showFormDataDialogFlag = false">
              {{ i18nt('designer.hint.closePreview') }}
            </el-button>
          </div>
        </template>
      </el-dialog>
    </div>

    <div v-if="showExportSFCDialogFlag" class="">
      <el-dialog
        draggable
        :title="i18nt('designer.toolbar.generateSFC')" v-model="showExportSFCDialogFlag" append-to-body
        v-if="showExportSFCDialogFlag" :show-close="true" class="drag-dialog small-padding-dialog" center
        width="65%" :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true">
        <el-tabs type="border-card" class="no-box-shadow no-padding" v-model="activeSFCTab">
          <el-tab-pane label="Vue2" name="vue2">
            <code-editor :mode="'html'" :readonly="true" v-model="sfcCode" :user-worker="false"></code-editor>
          </el-tab-pane>
          <el-tab-pane label="Vue3" name="vue3">
            <code-editor :mode="'html'" :readonly="true" v-model="sfcCodeV3" :user-worker="false"></code-editor>
          </el-tab-pane>
        </el-tabs>
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" class="copy-vue2-sfc-btn" :data-clipboard-text="sfcCode" @click="copyV2SFC">
              {{ i18nt('designer.hint.copyVue2SFC') }}
            </el-button>
            <el-button type="primary" class="copy-vue3-sfc-btn" :data-clipboard-text="sfcCodeV3" @click="copyV3SFC">
              {{ i18nt('designer.hint.copyVue3SFC') }}
            </el-button>
            <el-button @click="saveV2SFC">{{ i18nt('designer.hint.saveVue2SFC') }}</el-button>
            <el-button @click="saveV3SFC">{{ i18nt('designer.hint.saveVue3SFC') }}</el-button>
            <el-button @click="showExportSFCDialogFlag = false">
              {{ i18nt('designer.hint.closePreview') }}
            </el-button>
          </div>
        </template>
      </el-dialog>
    </div>

    <el-drawer :title="i18nt('designer.toolbar.nodeTreeTitle')" direction="ltr" v-model="showNodeTreeDrawerFlag"
               :modal="true" :size="280" append-to-body
               :destroy-on-close="true" class="node-tree-drawer">
      <el-tree ref="nodeTree" :data="nodeTreeData" node-key="id" default-expand-all highlight-current class="node-tree"
               icon-class="el-icon-arrow-right" @node-click="onNodeTreeClick"></el-tree>
    </el-drawer>

    <!--    页面选项-->
    <custom-dialog
      v-if="showCreateDialogFlag"
      v-model="showCreateDialogFlag"
      :title="createDialogTitle"
    >
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-row>
          <el-col>
            <el-form-item label="页面名称" prop="pageName">
              <el-input v-model="form.pageName" placeholder="请输入页面名称" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col>
            <el-form-item label="页面编号" prop="pageCode">
              <el-input v-model="form.pageCode" placeholder="请输入页面编号" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col>
            <el-form-item label="页面分类" prop="categId">
              <el-tree-select
                v-model="currentCategory"
                check-strictly
                clearable
                value-key="code"
                :props="{label:'name'}"
                :data="categoryList">
              </el-tree-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col>
            <el-form-item label="所属应用" prop="dependId">
              <el-select
                v-model="currentAppItem"
                placeholder="请选择所属应用"
                value-key="code"
                clearable
                filterable
              >
                <el-option
                  v-for="(item,index) in dependList"
                  :key="index"
                  :label="item.name"
                  :value="{ code: item.code, tenantId: item.tenantId }"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <!--        <el-row>
                  <el-col>
                    <el-form-item label="模型标签" prop="tags">
                      <template slot="label">
                        <span>模型标签</span>
                         <el-tooltip class="item" effect="light" content="允许通过设置标签的方式对平台上创建的实体进行分类" placement="right-start">
                          <i class="el-icon-question"/>
                        </el-tooltip>
                      </template>
                      <tags-popover size="large" v-model="form.tags"></tags-popover>
                    </el-form-item>
                  </el-col>
                </el-row>-->
        <el-row>
          <el-col>
            <el-form-item label="页面描述" prop="description">
              <el-input v-model="form.description" type="textarea" :rows="3" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <el-button @click="handleSubmit" type="primary">保存</el-button>
      </template>
    </custom-dialog>

    <custom-dialog
      v-if="showLogicEditorFlag"
      v-model="showLogicEditorFlag"
      title="逻辑编排"
      fullscreen
    >
      <login-editor></login-editor>
      <template #footer>
        <el-button @click="showLogicEditorFlag = false">关闭</el-button>
      </template>
    </custom-dialog>

  </div>
</template>

<script>
import CodeEditor from '@/components/code-editor/index'
import SvgIcon from '@/components/svg-icon'
import Clipboard from 'clipboard'
import { copyToClipboard, deepClone, findParents, generateId, getQueryParam, traverseAllWidgets } from '@/utils/util'
import XEUtils from 'xe-utils'
import i18n from '@/utils/i18n'
import { generateCode } from '@/utils/code-generator'
import { genSFC } from '@/utils/sfc-generator'
import loadBeautifier from '@/utils/beautifierLoader'
import { saveAs } from 'file-saver'
import CustomDialog from '@/components/common/custom-dialog/index.vue'
import { getApp, getComponentByCategoryId } from '@/api/applications'
import { ElLoading, ElMessage } from 'element-plus'
import { saveFormJson } from '@/api/form'
import LoginEditor from '@/components/logic-editor/index.vue'
import axios from 'axios'


export default {
  name: 'ToolbarPanel',
  mixins: [i18n],
  components: {
    LoginEditor,
    CustomDialog,
    // VFormRender,
    CodeEditor,
    SvgIcon,
    Clipboard,
  },
  props: {
    designer: Object,
    globalDsv: {
      type: Object,
      default: () => ({}),
    },
  },
  inject: ['getDesignerConfig', 'getTestOptionData'],
  data() {
    return {
      formJson: {},
      designerConfig: this.getDesignerConfig(),

      toolbarWidth: 450,
      showPreviewDialogFlag: false,
      showImportJsonDialogFlag: false,
      showExportJsonDialogFlag: false,
      showExportCodeDialogFlag: false,
      showFormDataDialogFlag: false,
      showExportSFCDialogFlag: false,
      showNodeTreeDrawerFlag: false,
      showLogicEditorFlag: false,
      nodeTreeData: [],
      formReadonlyFlag: false,

      importTemplate: '',
      jsonContent: '',
      jsonRawContent: '',

      formDataJson: '',
      formDataRawJson: '',

      vueCode: '',
      htmlCode: '',

      sfcCode: '',
      sfcCodeV3: '',

      activeCodeTab: 'vue',
      activeSFCTab: 'vue2',

      testFormData: {
        // 'userName': '666888',
        // 'productItems': [
        //   {'pName': 'iPhone12', 'pNum': 10},
        //   {'pName': 'P50', 'pNum': 16},
        // ]
      },
      showCreateDialogFlag: false,
      createDialogTitle: '页面保存',

      pageType: 'create',//表单保存状态，创建还是更新
      // pageFlag: 'vform', //页面标识，是page或者form等
      form: { //保存表单时需要的数据
        id: '',
        pageFlag: 'vform',//页面标识，是page或者form等
        pageName: '',
        pageCode: '',
        categId: '',
        dependId: '',
        // tags: '',
        description: '',
        tenantId: '',
        context: '',//表单json数据
      },
      rules: {
        pageName: [
          { required: true, message: '请输入页面名称', trigger: 'blur' },
        ],
        pageCode: [
          { required: true, message: '请输入页面编号', trigger: 'blur' },
        ],
        dependId: [
          { required: false, message: '请选择应用', trigger: ['blur', 'change'] },
        ],
      },
      dependList: [], //应用列表
      currentAppItem: {}, //当前所选应用
      currentCategory: '', //当前分类
      categoryList: [],//分类列表树形
      categoryListRaw: [],//分类列表数组
    }
  },
  computed: {
    undoDisabled() {
      return !this.designer.undoEnabled()
    },

    redoDisabled() {
      return !this.designer.redoEnabled()
    },

    layoutType() {
      return this.designer.getLayoutType()
    },

    designerDsv() {
      return this.globalDsv
    },

    testOptionData() {
      return this.getTestOptionData()
    },

    showLayoutTypeButton() {
      if (this.designerConfig['layoutTypeButton'] === undefined) {
        return true
      }

      return !!this.designerConfig['layoutTypeButton']
    },

  },
  /*  watch: {
      'designer.widgetList': {
        deep: true,
        handler(val) {
          //console.log('test-----', val)
          //this.refreshNodeTree()
        },
      },

    },*/
  created() {
    this.pageType = this.globalDsv?.pageData?.pageType


  },
  mounted() {

  },
  methods: {
    showToolButton(configName) {
      if (this.designerConfig[configName] === undefined) {
        return true
      }

      return !!this.designerConfig[configName]
    },

    buildTreeNodeOfWidget(widget, treeNode) {

      let curNode = {
        id: widget.id,
        label: widget.options.label ? widget.options.label + `(${widget.id})` : widget.id,
        type: widget.type,
        //selectable: true,
      }
      treeNode.push(curNode)

      if (widget.category === undefined) {
        return
      }

      curNode.children = []
      if (widget.type === 'grid' || widget.type === 'grid-adv') {
        widget.cols.map(col => {
          let colNode = {
            id: col.id,
            label: col.id || col.type,
            type: col.type,
            children: [],
          }
          curNode.children.push(colNode)
          col.widgetList.map(wChild => {
            this.buildTreeNodeOfWidget(wChild, colNode.children)
          })
        })
      } else if (widget.type === 'table') {
        //TODO: 需要考虑合并单元格！！
        widget.rows.map(row => {
          let rowNode = {
            id: row.id,
            label: 'table-row',
            type: widget.type,
            selectable: false,
            children: [],
          }
          curNode.children.push(rowNode)

          row.cols.map(cell => {
            if (!!cell.merged) {  //跳过合并单元格！！
              return
            }

            let rowChildren = rowNode.children
            let cellNode = {
              id: cell.id,
              label: 'table-cell',
              type: cell.type,
              children: [],
            }
            rowChildren.push(cellNode)

            cell.widgetList.map(wChild => {
              this.buildTreeNodeOfWidget(wChild, cellNode.children)
            })
          })
        })
      } else if (widget.type === 'tab') {
        widget.tabs.map(tab => {
          let tabNode = {
            id: tab.id,
            label: tab.options.name || widget.type,
            type: widget.type,
            selectable: false,
            children: [],
          }
          curNode.children.push(tabNode)
          tab.widgetList.map(wChild => {
            this.buildTreeNodeOfWidget(wChild, tabNode.children)
          })
        })
      } else if (widget.type === 'sub-form') {
        widget.widgetList.map(wChild => {
          this.buildTreeNodeOfWidget(wChild, curNode.children)
        })
      } else if (widget.type === 'data-table') {
        widget?.options?.tableColumns.map(col => {
          let columnNode = {
            id: col.columnId,
            label: col.label || col.prop,
            type: col.type,
            selectable: false,
            children: [],
          }
          curNode.children.push(columnNode)
          col?.widgetList?.map(wChild => {
            this.buildTreeNodeOfWidget(wChild, columnNode.children)
          })
        })
      } else if (widget.category === 'container') {  //自定义容器
        widget.widgetList.map(wChild => {
          this.buildTreeNodeOfWidget(wChild, curNode.children)
        })
      }
    },

    refreshNodeTree() {
      this.nodeTreeData.length = 0
      this.designer.widgetList.forEach(wItem => {
        this.buildTreeNodeOfWidget(wItem, this.nodeTreeData)
      })
    },

    showNodeTreeDrawer() {
      this.refreshNodeTree()
      this.showNodeTreeDrawerFlag = true
      this.$nextTick(() => {
        if (!!this.designer.selectedId) {  //同步当前选中组件到节点树！！！
          this.$refs.nodeTree.setCurrentKey(this.designer.selectedId)
        }
      })
    },

    undoHistory() {
      this.designer.undoHistoryStep()
      this.designer.emitEvent('canvas-undo', null)
    },

    redoHistory() {
      this.designer.redoHistoryStep()
      this.designer.emitEvent('canvas-redo', null)
    },

    changeLayoutType(newType) {
      this.designer.changeLayoutType(newType)
    },

    clearFormWidget() {
      this.designer.clearDesigner()
      this.designer.formWidget.clearWidgetRefList()

      this.designer.emitEvent('form-json-imported', [])  //通知其他组件
    },

    previewForm() {
      this.formJson.widgetList = deepClone(this.designer.widgetList)
      this.formJson.formConfig = deepClone(this.designer.formConfig)

      this.showPreviewDialogFlag = true
    },

    saveAsFile(fileContent, defaultFileName) {
      this.$prompt(this.i18nt('designer.hint.fileNameForSave'), this.i18nt('designer.hint.saveFileTitle'), {
        inputValue: defaultFileName,
        closeOnClickModal: false,
        inputPlaceholder: this.i18nt('designer.hint.fileNameInputPlaceholder'),
      }).then(({ value }) => {
        if (!value) {
          value = defaultFileName
        }

        if (getQueryParam('vscode') == 1) {
          this.vsSaveFile(value, fileContent)
          return
        }

        const fileBlob = new Blob([fileContent], { type: 'text/plain;charset=utf-8' })
        saveAs(fileBlob, value)
      }).catch(() => {
        //
      })
    },

    vsSaveFile(fileName, fileContent) {
      const msgObj = {
        cmd: 'writeFile',
        data: {
          fileName,
          code: fileContent,
        },
      }
      window.parent.postMessage(msgObj, '*')
    },

    importJson() {
      this.importTemplate = JSON.stringify(this.designer.getImportTemplate(), null, '  ')
      this.showImportJsonDialogFlag = true
    },

    doJsonImport() {
      try {
        let importObj = JSON.parse(this.importTemplate)
        //console.log('test import', this.importTemplate)
        if (!importObj || !importObj.formConfig) {
          throw new Error(this.i18nt('designer.hint.invalidJsonFormat'))
        }

        let fJsonVer = importObj.formConfig.jsonVersion
        if (!fJsonVer || (fJsonVer !== 3)) {
          throw new Error(this.i18nt('designer.hint.jsonVersionMismatch'))
        }
        console.log('doJsonImport', importObj)
        this.designer.loadFormJson(importObj)

        this.showImportJsonDialogFlag = false
        this.$message.success(this.i18nt('designer.hint.importJsonSuccess'))

        this.designer.emitHistoryChange()
      } catch (ex) {
        this.$message.error(ex + '')
      }
    },

    exportJson() {
      console.log('exportJson', this.designer.formConfig)
      let widgetList = deepClone(this.designer.widgetList)
      let formConfig = deepClone(this.designer.formConfig)
      this.jsonContent = JSON.stringify({ widgetList, formConfig }, null, '  ')
      this.jsonRawContent = JSON.stringify({ widgetList, formConfig })
      this.showExportJsonDialogFlag = true
    },

    copyFormJson(e) {
      copyToClipboard(this.jsonRawContent, e,
        this.$message,
        this.i18nt('designer.hint.copyJsonSuccess'),
        this.i18nt('designer.hint.copyJsonFail'),
      )
    },

    saveFormJson() {
      this.saveAsFile(this.jsonContent, `vform${generateId()}.json`)
    },

    exportCode() {
      this.formJson.widgetList = deepClone(this.designer.widgetList)
      this.formJson.formConfig = deepClone(this.designer.formConfig)
      this.vueCode = generateCode(this.formJson)
      this.htmlCode = generateCode(this.formJson, 'html')
      this.showExportCodeDialogFlag = true
    },

    copyVueCode(e) {
      copyToClipboard(this.vueCode, e,
        this.$message,
        this.i18nt('designer.hint.copyVueCodeSuccess'),
        this.i18nt('designer.hint.copyVueCodeFail'),
      )
    },

    copyHtmlCode(e) {
      copyToClipboard(this.htmlCode, e,
        this.$message,
        this.i18nt('designer.hint.copyHtmlCodeSuccess'),
        this.i18nt('designer.hint.copyHtmlCodeFail'),
      )
    },

    saveVueCode() {
      this.saveAsFile(this.vueCode, `vform${generateId()}.vue`)
    },

    saveHtmlCode() {
      this.saveAsFile(this.htmlCode, `vform${generateId()}.html`)
    },

    generateSFC() {
      loadBeautifier(beautifier => {
        this.sfcCode = genSFC(this.designer.formConfig, this.designer.widgetList, beautifier)
        this.sfcCodeV3 = genSFC(this.designer.formConfig, this.designer.widgetList, beautifier, true)
        this.showExportSFCDialogFlag = true
      })
    },

    copyV2SFC(e) {
      copyToClipboard(this.sfcCode, e,
        this.$message,
        this.i18nt('designer.hint.copySFCSuccess'),
        this.i18nt('designer.hint.copySFCFail'),
      )
    },

    copyV3SFC(e) {
      copyToClipboard(this.sfcCodeV3, e,
        this.$message,
        this.i18nt('designer.hint.copySFCSuccess'),
        this.i18nt('designer.hint.copySFCFail'),
      )
    },

    saveV2SFC() {
      this.saveAsFile(this.sfcCode, `vformV2-${generateId()}.vue`)
    },

    saveV3SFC() {
      this.saveAsFile(this.sfcCodeV3, `vformV3-${generateId()}.vue`)
    },

    getFormData() {
      console.log('toolbar getFormData')
      this.$refs['preForm'].getFormData().then(formData => {
        this.formDataJson = JSON.stringify(formData, null, '  ')
        this.formDataRawJson = JSON.stringify(formData)

        this.showFormDataDialogFlag = true
      }).catch(error => {
        this.$message.error(error)
      })
    },

    copyFormDataJson(e) {
      copyToClipboard(this.formDataRawJson, e,
        this.$message,
        this.i18nt('designer.hint.copyJsonSuccess'),
        this.i18nt('designer.hint.copyJsonFail'),
      )
    },

    saveFormData() {
      this.saveAsFile(this.formDataJson, `formData${generateId()}.json`)
    },

    resetForm() {
      this.$refs['preForm'].resetForm()
    },

    setFormDisabled() {
      this.$refs['preForm'].disableForm()
    },

    setFormEnabled() {
      this.$refs['preForm'].enableForm()
    },

    switchReadMode() {
      this.formReadonlyFlag = !this.formReadonlyFlag
      this.$refs['preForm'].setReadMode(this.formReadonlyFlag)
    },

    handleFormChange(fieldName, newValue, oldValue, formModel) {
      /*
      console.log('---formChange start---')
      console.log('fieldName', fieldName)
      console.log('newValue', newValue)
      console.log('oldValue', oldValue)
      console.log('formModel', formModel)
      console.log('---formChange end---')
      */
    },

    testOnAppendButtonClick(clickedWidget) {
      console.log('test', clickedWidget)
    },

    testOnButtonClick(button) {
      console.log('test', button)
    },

    testDTSC(dt, s1, s2) {
      // console.log('test dt', dt)
      // console.log('test s1', s1)
      // console.log('test s2', s2)
    },

    testOBC(aa) {
      console.log('test=====', aa)
    },

    onMyEmitTest(aaa) {
      console.log('test emit', aaa)
    },

    findWidgetById(wId) {
      let foundW = null
      traverseAllWidgets(this.designer.widgetList, (w) => {
        if (w.id === wId) {
          foundW = w
        }
      })

      return foundW
    },

    onNodeTreeClick(nodeData, node, nodeEl) {
      //console.log('test', JSON.stringify(nodeData))
      if ((nodeData.selectable !== undefined) && !nodeData.selectable) {
        this.$message.info(this.i18nt('designer.hint.currentNodeCannotBeSelected'))
      } else {
        const selectedId = nodeData.id
        const foundW = this.findWidgetById(selectedId)
        if (!!foundW) {
          this.designer.setSelected(foundW)
        }
      }
    },
    handleSaveForm() {
      if (this.pageType === 'create') {
        getApp().then((response) => {
          this.dependList = response.data
        })
        //此处获取页面分类，正常应该用this.form.pageFlag，此处暂时固定为page
        getComponentByCategoryId('page').then((response) => {
          this.categoryListRaw = response.data
          this.categoryList = XEUtils.toArrayTree(response.data, {
            parentKey: 'parentCode',
            key: 'code',
          })
        })
        this.showCreateDialogFlag = true
      } else {
        this.handleSubmit()
      }
    },
    handleSubmit() {
      if (this.pageType === 'create') {
        this.form.dependId = this.currentAppItem.code
        this.form.tenantId = this.currentAppItem.tenantId
        this.form.categId = this.getCategoryId(this.currentCategory)
      } else {
        this.form.id = this.globalDsv.pageData.pageId
        this.form.pageFlag = this.globalDsv.pageData.pageFlag
        this.form.pageCode = this.globalDsv.pageData.pageCode
        this.form.dependId = this.globalDsv.pageData.dependId
        this.form.tenantId = this.globalDsv.pageData.tenantId
        this.form.pageName = this.globalDsv.pageData.pageName
        this.form.categId = this.globalDsv.pageData.categId
      }
      let widgetList = deepClone(this.designer.widgetList)
      let formConfig = deepClone(this.designer.formConfig)
      this.form.context = JSON.stringify({ widgetList, formConfig })
      const loading = ElLoading.service({
        lock: true,
        text: '页面保存中',
        background: 'rgba(0, 0, 0, 0.7)',
      })
      saveFormJson(this.form).then(response => {
        ElMessage.success('保存成功!')
      }).finally(() => {
        loading.close()
      })
    },
    getCategoryId(code) {
      let parentCodeList = findParents(this.categoryList, code)
      let parentIdArr = []
      this.categoryListRaw.forEach((item) => {
        parentCodeList.forEach((item2) => {
          if (item.code == item2) {
            parentIdArr.push(item.id)
          }
        })
      })
      parentIdArr.unshift(this.form.pageFlag)
      const parentIds = parentIdArr.join(',')
      return parentIds
    },
    async postToNodeRed() {
      const preForm = this.$refs.preForm
      const formDataModel = preForm.formDataModel
      console.log(formDataModel)
      const res = await axios.post('http://127.0.0.1:1880/form', formDataModel)
      console.log('res', res)
      preForm.setFormData(res.data)
      // axios.get('http://127.0.0.1:1880/test?a=1')
    },
  },
}
</script>

<style lang="scss" scoped>

.preview_wrapper {
  :deep(.ep-dialog) {
    width: calc(100vw - 200px);
  }
}

.toolbar-container {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
}


.left-toolbar {
  display: flex;
  margin-top: 4px;
  float: left;
  font-size: 16px;
}

.right-toolbar {
  line-height: 42px;
  text-align: right;
  overflow: hidden;

  .right-toolbar-con {
    //display:inline-block;
    //text-align: left;
    display: flex;
    justify-content: flex-end;
    //min-width: 450px;
    height: 42px;
  }

  :deep(.ep-button) {
    margin-left: 10px;
  }

  :deep(.ep-button--text) {
    font-size: 14px !important;
  }

  :deep(.svg-icon) {
    margin-left: 0;
    margin-right: 0.05em;
  }
}

.ep-button i {
  margin-right: 3px;
}


.small-padding-dialog {

  :deep(.ep-dialog__header) {
    //padding-top: 3px;
    //padding-bottom: 3px;
    background: #f1f2f3;
  }

  :deep(.ep-dialog__body) {
    padding: 12px 15px 12px 15px;

    .ep-alert.alert-padding {
      padding: 0 10px;
    }
  }

  :deep(.ace-container) {
    border: 1px solid #DCDFE6;
  }
}

.dialog-title-light-bg {
  :deep(.ep-dialog__header) {
    background: #f1f2f3;
  }
}

.no-box-shadow {
  box-shadow: none;
}

.no-padding.ep-tabs--border-card {
  :deep(.ep-tabs__content) {
    padding: 0;
  }
}

.form-render-wrapper {
  //height: calc(100vh - 142px);
  //all: revert !important; /* 防止表单继承el-dialog等外部样式，未生效，原因不明？？ */
}

.form-render-wrapper.h5-layout {
  margin: 0 auto;
  width: 420px;
  border-radius: 15px;
  //border-width: 10px;
  box-shadow: 0 0 1px 10px #495060;
  height: calc(100vh - 175px);
  overflow-y: auto;
  overflow-x: hidden;
}

.form-render-wrapper.pad-layout {
  margin: 0 auto;
  width: 960px;
  border-radius: 15px;
  //border-width: 10px;
  box-shadow: 0 0 1px 10px #495060;
  height: calc(100vh - 175px);
  overflow-y: auto;
  overflow-x: hidden;
}

.node-tree-drawer {
  :deep(.ep-drawer) {
    padding: 10px;
    overflow: auto;
  }

  :deep(.ep-drawer__header) {
    margin-bottom: 12px;
    padding: 5px 5px 0;
  }

  :deep(.ep-drawer__body) {
    padding-left: 5px;
  }
}

/*.node-tree-scroll-bar {*/
/*  height: 100%;*/
/*  overflow: auto;*/
/*}*/

:deep(.node-tree) {
  .ep-tree > .ep-tree-node:after {
    border-top: none;
  }

  .ep-tree-node {
    position: relative;
    padding-left: 12px;
  }

  .ep-tree-node__content {
    padding-left: 0 !important;
  }

  .ep-tree-node__expand-icon.is-leaf {
    display: none;
  }

  .ep-tree-node__children {
    padding-left: 12px;
    overflow: visible !important; /* 加入此行让el-tree宽度自动撑开，超出宽度el-draw自动出现水平滚动条！ */
  }

  .ep-tree-node :last-child:before {
    height: 38px;
  }

  .ep-tree > .ep-tree-node:before {
    border-left: none;
  }

  .ep-tree > .ep-tree-node:after {
    border-top: none;
  }

  .ep-tree-node:before {
    content: "";
    left: -4px;
    position: absolute;
    right: auto;
    border-width: 1px;
  }

  .ep-tree-node:after {
    content: "";
    left: -4px;
    position: absolute;
    right: auto;
    border-width: 1px;
  }

  .ep-tree-node:before {
    border-left: 1px dashed #4386c6;
    bottom: 0px;
    height: 100%;
    top: -10px;
    width: 1px;
  }

  .ep-tree-node:after {
    border-top: 1px dashed #4386c6;
    height: 20px;
    top: 12px;
    width: 16px;
  }

  .ep-tree-node.is-current > .ep-tree-node__content {
    background: #c2d6ea !important;
  }

  .ep-tree-node__expand-icon {
    margin-left: -3px;
    padding: 6px 6px 6px 0px;
    font-size: 16px;
  }

}
</style>
